#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.59])
AC_INIT([Sunrise], [3.0], [Patrik Jonsson <sunrise@familjenjonsson.org>])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/mcrx.h])
AM_CONFIG_HEADER(src/config.h)
AM_INIT_AUTOMAKE
#LT_PREREQ([2.2])
#LT_INIT
AM_PROG_LIBTOOL

# Checks for programs.
AC_PROG_CXX
AC_LANG_CPLUSPLUS
#AC_PROG_CC
AC_PROG_RANLIB

# Check if the script was called with --enable-64bit
# and if so modify the compilation flags.
AC_COMPILERS_ENABLE_64BITS

# check for restrict, because if it's valid, blitz has been compiled with it
AC_CXX_NCEG_RESTRICT
AC_CXX_NCEG_RESTRICT_EGCS

# check for large file support
AC_SYS_LARGEFILE

# Check for thread support
#m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
ACX_PTHREAD(,AC_MSG_ERROR([Can't find support for POSIX threads]))

# Checks for header files.
AC_HEADER_STDC
#AC_CHECK_HEADERS([stdlib.h string.h unistd.h],,[Headers not found])

# Checks for library functions.
AC_CHECK_FUNCS([acl pow sqrt])

# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_STRUCT_TM


# Check for required libraries and headers

AX_BOOST_BASE([1.40.0])
AX_BOOST_THREAD
AX_BOOST_PROGRAM_OPTIONS
AX_BOOST_SERIALIZATION(,[AC_MSG_ERROR([Could not find Boost::Serialization library])])

AC_ARG_WITH([mpi], [  --with-mpi             Use MPI to enable shared-memory parallelism],
		   [
		   # The problem with MPI is that mpic++ is hardwired
		   # to use the default compiler. Thus we can't
		   # redefine CXX and have it work. What we do instead
		   # is check for mpi and then extract the mpi flags
		   # so we don't have to use the wrapper
		   CXXFLAGS_save=$CXXFLAGS
		   LDFLAGS_save=$LDFLAGS
		   CXXFLAGS=""
		   LDFLAGS=""
		   AX_MPI
		   MPI_CXXFLAGS=`$MPICXX --showme:compile`
		   [echo Using MPI_CXXFLAGS=$MPI_CXXFLAGS]
		   AC_SUBST(MPI_CXXFLAGS)
		   MPI_LDFLAGS=`$MPICXX --showme:link`
		   [echo Using MPI_LDFLAGS=$MPI_LDFLAGS]
		   AC_SUBST(MPI_LDFLAGS)
		   CXXFLAGS="$CXXFLAGS_save $MPI_CXXFLAGS"
		   LDFLAGS="$LDFLAGS_save $MPI_LDFLAGS"

AC_CHECK_HEADERS([boost/mpi.hpp])
AC_CHECK_LIB([boost_mpi],[main],,AC_MSG_ERROR([Could not find Boost::MPI library.]))

		   [am_mpi=true]]
		   , [am_mpi=false])
AM_CONDITIONAL([WITH_MPI], [test x$am_mpi = xtrue])


AC_CHECK_HEADERS([tbb/concurrent_queue.h])
AC_CHECK_LIB([tbb],[main],,AC_MSG_ERROR([Could not find TBB library.]))

# Checks for thread binding  /NUMA APIs
AC_CHECK_HEADERS([numa.h])
AC_CHECK_LIB([numa],[numa_bitmask_isbitset])
AC_CHECK_FUNCS([sched_setaffinity bindprocessor numa_bitmask_isbitset numa_node_size numa_distance numa_set_interleave_mask])

AC_ARG_ENABLE([tcmalloc],[  --enable-tcmalloc       use tcmalloc for memory allocations],
			    AC_CHECK_LIB([tcmalloc_minimal],[malloc]),
			    AC_MSG_WARN([libtcmalloc_minimal not found]))

AC_CHECK_LIB([hdf5],[main],, AC_MSG_WARN(HDF5 library not found))
AC_CHECK_LIB([hdf5_cpp],[main],, AC_MSG_WARN(HDF5 C++ library not found))
AC_CHECK_HEADERS([H5Cpp.h],,AC_MSG_WARN(HDF5 C++ headers not found))

AC_CHECK_LIB([papi],[main])

# see if we have copy_if, which is included in c++0x
AC_MSG_CHECKING([for std::copy_if])
AC_TRY_COMPILE([
#include<vector>
#include<algorithm>
bool predicate(int);
],[
std::vector<int> v; 
std::vector<int>::iterator i=v.begin();
std::copy_if(i,i,i, predicate);
], AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_COPY_IF],[1],[copy_if exists in <algorithm>]),
AC_MSG_RESULT([no])  ) 

AC_ARG_ENABLE([tests],[  --enable-tests          enable unit tests],
			 [[echo Enabling unit tests]
			 AC_CHECK_LIB([UnitTest++], [main],,AC_MSG_ERROR([UnitTest++ library not found]))
			 AC_CHECK_HEADERS([UnitTest++.h],,AC_MSG_ERROR([UnitTest++.h header not found]))
			 [am_unittest=true]],
			 [am_unittest=false])
AM_CONDITIONAL([ENABLE_TEST], [test x$am_unittest = xtrue])


# check for CUDA and nvcc, if the option is set
AC_ARG_WITH([cuda], [  --with-cuda             Use CUDA GPU code to accelerate calculations],
	[[echo Using CUDA]
	AC_CHECK_PROG(nvcc,[nvcc],[nvcc],AC_MSG_ERROR(nvcc not found))
	#AC_CHECK_HEADERS([cutil.h],,AC_MSG_ERROR(cutil.h not found)) needs nvcxxflags to work
	AC_CHECK_LIB([cutil],[main],[CUTIL_LIB=-lcutil], AC_CHECK_LIB([cutil_x86_64],[main],[CUTIL_LIB=-lcutil_x86_64], AC_MSG_ERROR(CUDA utility library not found)))
	AC_CHECK_LIB([cudart],[main],, AC_MSG_ERROR(CUDA runtime library not found))

	AC_SUBST(CUTIL_LIB)
	AC_SUBST(NVCXXFLAGS)
	AC_DEFINE([WITH_CUDA],1,[Compile in support for CUDA])
	[am_cudafiles=true]]
	, [am_cudafiles=false])
 
AM_CONDITIONAL([WITH_CUDA], [test x$am_cudafiles = xtrue])

AC_ARG_WITH([x11], [  --with-x11            Use X11 to display a progress window],
		   [[echo Using X11]
		   AC_CHECK_HEADERS([X11/Xlib.h GL/gl.h GL/glu.h GL/glx.h],,AC_MSG_ERROR(X11/OpenGL headers not found))
		   AC_CHECK_LIB([X11],[main],, AC_MSG_ERROR(X11 library not found))
		   AC_CHECK_LIB([GL],[main],, AC_MSG_ERROR(OpenGL library not found))
		   AC_CHECK_LIB([GLU],[main],, AC_MSG_ERROR(OpenGLU library not found))
		   AC_DEFINE([WITH_X11],1,[Compile in support for X11])
		   [am_x11=true]]
		   , [am_x11=false])
AM_CONDITIONAL([WITH_X11], [test x$am_x11 = xtrue])

AC_ARG_WITH([arepo], [  --with-arepo            Link with Arepo to handle Arepo snapshots directly],
		   [[echo Checking for Arepo]

		   AC_CHECK_LIB([gslcblas],[main],, AC_MSG_ERROR(Gsl cblas library not found))
		   AC_CHECK_LIB([gsl],[main],, AC_MSG_ERROR(Gsl library not found))
		   AC_CHECK_LIB([gmp],[main],, AC_MSG_ERROR(Gmp library not found))

		   # XXX mpi
		   AC_CHECK_HEADERS([allvars.h proto.h],,AC_MSG_ERROR(Arepo headers not found))
		   AC_CHECK_LIB([arepo],[main],, AC_MSG_ERROR(Arepo library not found))
		   AC_DEFINE([WITH_AREPO],1,[Compile in support for Arepo])
		   #		   CXXFLAGS="$CXXFLAGS_save 
		  #LDFLAGS=$LDFLAGS_save
		   [am_arepo=true]]
		   , [am_arepo=false])
AM_CONDITIONAL([WITH_AREPO], [test x$am_arepo = xtrue])

# blitz (and headers that use blitz) needs to be checked with the
# pthread compiler options, and libPJutil needs to be compiled with
# boost_thread due to the static initializer in the hpm
# library. Becasue AC_CHECK_LIB pulls in -lPJutil, we do this check
# last so it doesn't screw up the tests of the libraries above that
# don't need libPJutil.
CXXFLAGS_save=$CXXFLAGS
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS $BOOST_LDFLAGS $BOOST_THREAD_LIB"
AC_CHECK_LIB(blitz,main,,AC_MSG_ERROR(Blitz library not found))
AC_CHECK_HEADERS([blitz/array.h random/uniform.h],,AC_MSG_ERROR(Blitz headers not found))

AC_CHECK_LIB([cfitsio], main,,AC_MSG_ERROR(cfitsio library not found))
AC_CHECK_HEADERS([fitsio.h],,AC_MSG_ERROR(cfitsio headers not found))

AC_CHECK_LIB(CCfits,main,,AC_MSG_ERROR(CCfits library not found))
AC_CHECK_HEADERS([CCfits/CCfits],,AC_MSG_ERROR(CCfits headers not found))
AC_CHECK_LIB([PJutil],[_ZN10binfstreamD0Ev],, AC_MSG_ERROR(PJutil library not found))
AC_CHECK_HEADERS([biniostream.h counter.h hpm.h message.h constants.h preferences.h interpolatort.h solver2.h  ],,AC_MSG_ERROR(PJutil headers not found))
CXXFLAGS=$CXXFLAGS_save

AC_CONFIG_FILES([Makefile src/Makefile test/Makefile util/Makefile unittest/Makefile])
AC_OUTPUT
